package tw.edu.tku.im.maze;

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.example.maze.Edge;
import com.example.maze.Graph;
import com.example.maze.SpanningTree;
import com.example.maze.Vertex;

public class MazeMap {
   
   long[] edges;
   int M,N,times;
   
   //-------------------------------------------------------
   public static MazeMap getMazeMap(int mapLv) {
      if(mapLv<1 || mapLv>10){ throw new IllegalArgumentException(); }
      switch(mapLv) {
         case 1:
            return new MazeMap(18, 18, 180);
         case 2:
            return new MazeMap(23, 23, 210);
         case 3:
            return new MazeMap(28, 28, 240);
         case 4:
            return new MazeMap(33, 33, 300);
         case 5:
            return new MazeMap(38, 38, 360);
         case 6:
            return new MazeMap(43, 43, 420);
         case 7:
            return new MazeMap(48, 48, 480);
         case 8:
            return new MazeMap(53, 53, 540);
         case 9:
            return new MazeMap(58, 58, 570);
         case 10:
            return new MazeMap(63, 63, 600);
      }
      return null;
   }
   
   public static MazeMap parse(JSONObject jsonMap) throws JSONException {
      JSONArray jsonEdges = jsonMap.getJSONArray("edges");
      long[] edges = new long[jsonEdges.length()];
      for(int i=0; i<jsonEdges.length(); i++) {
         edges[i] = jsonEdges.getLong(i);
      }
      int M = jsonMap.getInt("M");
      int N = jsonMap.getInt("N");
      //int pixels = jsonMap.getInt("pixels");
      int time = jsonMap.getInt("time");
      return new MazeMap(edges, M, N, time);
   }
   
   //-------------------------------------------------------
   public MazeMap(int m ,int n, int time) {
      this.M = m;
      this.N = n;
      this.edges = this.server(M, N);
      this.times = time;
   }
   
   public MazeMap(long[] edges, int m ,int n, int time) {
      this.M = m;
      this.N = n;
      setEdges(edges);
      this.times = time;
   }
   
   
   //-------------------------------------------------------
   public void setM(int m) {
      this.M = m;
   }
   public int getM() {
      return M;
   }
   
   //-------------------------------------------------------
   public void setN(int n) {
      this.N = n;
   }
   public int getN() {
      return N;
   }
   
   //-------------------------------------------------------
   public void setEdges(long[] edges) {
      this.edges = edges;
   }
   public long[] getEdges() {
      return edges;
   }
   
   private long[] server(int M,int N) {  
      Vertex[][] vs= new Vertex[M][N];
      for(int i=0; i<M; i++) {
         for(int j=0; j<N; j++) {
            vs[i][j]= new Vertex(i,j);
         }
      }        
      SpanningTree.setData(M,N,vs,Graph.newGraph(M,N,vs));  
      ArrayList<Edge> st= SpanningTree.getTree();       
      long[] indexArr= new long[st.size()];
      for(int i=0; i<st.size(); i++) {
         indexArr[i]= st.get(i).index(M,N);
      }      
      return indexArr;
   }
   
   //-------------------------------------------------------
   public String toString() {
      StringBuilder ans = new StringBuilder("{ \"edges\" : [");
      for(int i=0; i<this.edges.length; i++) {
         if(i==this.edges.length-1) {
            ans.append(edges[i]).append("], \"M\" : ");
         }
         else {
            ans.append(edges[i]).append(",");
         }
      }
      ans.append(this.M).append(", ").append("\"N\" : ")
         .append(this.N).append(", ").append("\"time\" : ")
         //.append(this.N).append(", ").append("\"pixels\" : ")
         //.append(this.pixels).append(", ").append("\"time\" : ")
         .append(this.times).append(" }");
      return ans.toString();
   }
   
   //-------------------------------------------------------
   public String toJSONString() throws JSONException {
      JSONObject map = new JSONObject();
      JSONArray edges = new JSONArray();
      for(long i : this.edges) {
         edges.put(i);
      }
      map.put("edges", edges);
      map.put("M", this.M);
      map.put("N", this.N);
      //map.put("pixels", this.pixels);
      map.put("time", this.times);
      return map.toString();
   }
   
   public static void main(String[] args) {
      MazeMap map = MazeMap.getMazeMap(4);
      System.out.println(map.edges.length);
      System.out.println(map.toJSONString().length());
      System.out.println(map.toJSONString());
   }
}
